%%%-------------------------------------------------------------------
%%% File    : slave_sup.erl
%%% Author  :  <>
%%% Description : 
%%%
%%% Created : 16 Mar 2011 by  <>
%%%-------------------------------------------------------------------
-module(slave_sup).

-behaviour(gen_server).

-export([start/1]).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
	terminate/2, code_change/3]).

-define(Sup, dis_sup).

-record(sup, {master_sup,
	     slave_sup}).
%%-------
start(Parent) ->
    gen_server:start(?MODULE, [Parent], []).

%%-------
init([Parent]) ->
    process_flag(trap_exit, true),
    State = #sup{master_sup=Parent, %%%first is pid, later will be node
		slave_sup=[]},
    {ok, State}.

handle_call(_Req, _From, S) ->
    {reply, ok, S}.

%%handle_cast({do_exit, Pid}, #sup{master_sup=Msup}) when Msup =:= Pid->
%%    exit(normal);
handle_cast({del, Pid}, #sup{master_sup=Msup}) when Msup =:= Pid->
    exit(normal);
handle_cast(_Res, S) ->
    {noreply, S}.

handle_info({'EXIT', _Pid, normal}, S) ->
    {noreply, S};
handle_info({'EXIT', Pid, shutdown}, S=#sup{master_sup=Msup}) ->
    case Pid =:= Msup of
	true ->
	    exit(normal);
	false ->
	    {noreply, S} 
    end;
handle_info({'EXIT', Pid, noconnection}, S=#sup{master_sup=Msup}) ->
    Ns = case Pid =:= Msup of
	     true ->
		 become_msup(S);
	     false ->
		 S
         end,
    {noreply, Ns};
handle_info({'EXIT', Pid, _Reason}, S=#sup{master_sup=Msup}) when Pid =:= Msup->
    Msup1 = redirect(),
    {noreply, S#sup{master_sup=Msup1}};
handle_info(_Info, S) ->
    {noreply, S}.

terminate(_Reason, _S) ->
    ok.

code_change(_Oldvsn, S, _Extra) ->
    {ok, S}.

%%------internal
become_msup(S) ->
    case application:start(chat) of
	ok ->
	    exit(normal);
	{error, _Reason} ->
	    Msup = redirect(),
	    S#sup{master_sup=Msup}
    end.

redirect() ->
    case global:whereis_name(dis_sup) of
	Pid when is_pid(Pid) ->
	    link(Pid),
	    gen_server:cast(Pid, {redirect, node(), self()}),
	    Pid;
	undefined ->
	    sleep(1000),
	    redirect()
    end.

sleep(Time) ->
    receive
    after Time ->
	    ok
    end.
